home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / basic / qbnws105.zip / QBFORMAT.ZIP / INTRPT.ASM next >
Assembly Source File  |  1989-03-14  |  15KB  |  366 lines

  1.        TITLE   INTERRUPT - BASCOM software interrupt calling routine
  2.         PAGE    56,132
  3. ;***
  4. ; INTERRUPT - BASCOM software interrupt calling routine
  5. ;
  6. ;       Copyright <C> 1986, 1987 Microsoft Corporation
  7. ;
  8. ;Purpose:
  9. ;   Allows a BASIC program to invoke an interrupt through a CALL statement.
  10. ;
  11. ;   INTERRUPT allows BASIC to set AX,BX,CX,DX,BP,SI,DI, and the flags
  12. ;   before the call.  INTERRUPTX also allows DS and ES to be set.
  13. ;   Both routines will return the values of the registers upon the
  14. ;   completion of a successful call.  If the interrupt could not
  15. ;   be generated (due to a bad interrupt number or an illegal array)
  16. ;   then the interrupt number will be set to -1 to indicate an error.
  17. ;
  18. ;******************************************************************************
  19. ;
  20. ;Note:
  21. ;   The DOSSEG, .MODEL, .CODE, and .DATA? directives used in this program
  22. ;   are part of the simplified segment system of MASM 5.0. If you have
  23. ;   an earlier version of MASM, you must modify the source to define
  24. ;   the segments required by Microsoft high-level languages. These
  25. ;   segments are discussed in Appendix C of "Learning and Using QuickBASIC."
  26. ;
  27.  
  28. ;       Frame structure definition
  29.  
  30. ARG1    =       0AH             ;pointer to first of three arguments
  31. ARG2    =       08H             ;pointer to second of three arguments
  32. ARG3    =       06H             ;pointer to third of three arguments
  33.  
  34. ;       Frame temp variables
  35.  
  36. UCODE_FLGS =    -02H            ;user code flag register value
  37. UCODE_DS =      -04H            ;user code DS register value
  38. REG_NUM =       -06H            ;number of regs used (INTERRUPT=8, INTERRUPTX=10)
  39. INT_ES  =       -08H            ;INT ES register value
  40. INT_DS  =       -0AH            ;INT DS register value
  41. INT_FLGS =      -0CH            ;INT flags register value
  42. INT_DI  =       -0EH            ;INT DI register value  (was -1EH, bug)
  43. INT_SI  =       -10H            ;INT SI register value
  44. INT_BP  =       -12H            ;INT BP register value
  45. INT_DX  =       -14H            ;INT DX register value
  46. INT_CX  =       -16H            ;INT CX register value
  47. INT_BX  =       -18H            ;INT BX register value
  48. INT_AX  =       -1AH            ;INT AX register value
  49. OLD_SI  =       -1CH            ;save old SI for interpreter
  50. OLD_DI  =       -1EH            ;save old DI for interpreter
  51.  
  52. FRM_SIZ =       -1EH            ;negative size of frame temporaries
  53.  
  54. ;       Locations past frame allocation used to recover post-INT BP value.
  55.  
  56. INT_BP_TMP =    -22H            ;temp location for INT BP register value
  57.  
  58. ;***
  59. ; INTERRUPT, and INTERRUPTX - BASCOM software interrupt calling interface
  60. ;
  61. ; Purpose:
  62. ;       To allow a BASIC Compiler program to perform any software
  63. ;       interrupt.  The interrupt is executed with the registers
  64. ;       set to values specified in a register variable.  The post-
  65. ;       interrupt values of the registers are then stored in
  66. ;       another register  RegType[X],
  67. ;                          outreg AS RegType[X])
  68. ;
  69. ; Inputs:
  70. ;       int_no = interrupt number (range 0 to 255) to execute
  71. ;       inreg and outreg are register variables of type RegType[X]
  72. ;       defined as follows;
  73. ;
  74. ; TYPE RegType
  75. ;     ax    AS INTEGER
  76. ;     bx    AS INTEGER
  77. ;     cx    AS INTEGER
  78. ;     dx    AS INTEGER
  79. ;     bp    AS INTEGER
  80. ;     si    AS INTEGER
  81. ;     di    AS INTEGER
  82. ;     flags AS INTEGER
  83. ; END TYPE
  84. ;
  85. ;
  86. ; TYPE RegTypeX
  87. ;     ax    AS INTEGER
  88. ;     bx    AS INTEGER
  89. ;     cx    AS INTEGER
  90. ;     dx    AS INTEGER
  91. ;     bp    AS INTEGER
  92. ;     si    AS INTEGER
  93. ;     di    AS INTEGER
  94. ;     flags AS INTEGER
  95. ;     ds    AS INTEGER
  96. ;     es    AS INTEGER
  97. ; END TYPE
  98. ;
  99. ; Outputs:
  100. ;       If no error:
  101. ;               int_no = unchanged (range 0 to 255)
  102. ;               outreg: This array will be set to the post-interrupt
  103. ;                       register values.  It has the same structure
  104. ;                       as inreg.
  105. ;       If error:
  106. ;               int_no = -1
  107. ;               outreg unchanged.  INT call is not performed.
  108. ;               error occurs:
  109. ;                       first argument not 0 to 255 (2^8-1)
  110. ;                       second or third arguments not  0 to 1048575 (2^20-1)
  111. ;                               (VARPTR will always be in this range)
  112. ;
  113. ; Modifies:
  114. ;       All, except BP, DS, and flags.
  115. ;       Also, possible side effects of INT call.
  116. ;
  117. ; Exceptions:
  118. ;       INT 24H call may result from some INT 21H MS-DOS calls.
  119. ;
  120. ;******************************************************************************
  121. _bss            segment word PUBLIC 'data'
  122. _bss    ends
  123.  
  124. _data           segment word PUBLIC 'data'
  125. _data   ends
  126.  
  127. dgroup  group   _bss, _data
  128.  
  129. Intrpt_TEXT     segment word PUBLIC 'code'
  130.         assume cs:Intrpt_TEXT, ds:dgroup, es:dgroup, ss:dgroup
  131.  
  132.         PUBLIC INTERRUPT
  133. INTERRUPT PROC  FAR
  134.  
  135.         PUSH    BP              ;save BASCOM frame pointer on stack
  136.         MOV     BP,SP           ;establish program frame reference
  137.         ADD     SP,FRM_SIZ      ;allocate working space for frame
  138.         MOV     WORD PTR [BP].REG_NUM,08H ;eight regs used (not DS or ES)
  139.         JMP     SHORT INTERRUPT_COMMON ;jump to common code
  140.  
  141. INTERRUPT ENDP
  142.  
  143.         PUBLIC INTERRUPTX
  144. INTERRUPTX PROC FAR
  145.  
  146.         PUSH    BP              ;save BASCOM frame pointer on stack
  147.         MOV     BP,SP           ;establish program frame reference
  148.         ADD     SP,FRM_SIZ      ;allocate working space for frame
  149.         MOV     WORD PTR [BP].REG_NUM,0AH ;ten regs used (including DS and ES)
  150.  
  151. ;       Save a copy of the processor flags, SI, DI, and DS in the stack frame.
  152.  
  153. INTERRUPT_COMMON:
  154.         MOV     [BP].OLD_SI,SI  ;save old SI for interpreter
  155.         MOV     [BP].OLD_DI,DI  ;save old DI for interpreter
  156.         MOV     [BP].UCODE_DS,DS;save DS for interpreter
  157.         PUSHF                   ;push the flags on the stack
  158.         POP     [BP].UCODE_FLGS ;put value in the stack frame
  159.  
  160. ;       Move eight or ten words (depending if executing INTERRUPT or INTERRUPTX)
  161. ;       of the integer input array from the far pointer computed to the frame.
  162.  
  163.         MOV     SI,[BP].ARG2    ;and array offset - pointer in DS:SI
  164.         LEA     DI,[BP].INT_AX  ;get start of temporary register storage.
  165.         MOV     CX,[BP].REG_NUM ;eight or ten words to move
  166.         CLD                     ;movement is to higher memory
  167.         PUSH    SS
  168.         POP     ES
  169.         REP     MOVSW           ;move the array into the stack frame
  170.  
  171. ;       Save stack frame pointer to recover its value after the INT call.
  172.  
  173.         PUSH    BP              ;saved to first word past the stack frame
  174.  
  175. ;       Create a two-instruction program on the stack to execute the
  176. ;       INT call requested and return with stack cleanup.
  177. ;
  178. ;       INT     XX      (hex: CD XX)
  179. ;       RETF    06      (hex: CA 06 00)
  180. ;
  181. ;       In the case of INT 25 and 26 (which leave a word of flags on the stack)
  182. ;       We generate:
  183. ;
  184. ;       INT     XX      (hex: CD XX)
  185. ;       ADD     SP,2    (hex: 83 C4 02)     ;this trashes ALL math flags incl CF
  186. ;       RETF    08      (hex: CA 08 00)
  187. ;----------debugged--- CHH solution
  188. ;       INT     XX      (hex: CD XX)
  189. ;       inc     sp      (hex: 44)
  190. ;       inc     sp      (hex: 44)
  191. ;       nop             (hex: 90)
  192. ;       RETF    08      (hex: CA 08 00)
  193. ;
  194.         MOV     SI,[BP].ARG1    ;[SI] = ptr to first CALL arg - interrupt #
  195.         MOV     BX,[SI]         ;[BL] = get integer value of INT type
  196.         OR      BH,BH           ;test if in range, 00 to FFH is legal
  197.         JZ      NO_INT_ERROR    ;if not, then error - jump
  198.         JMP     INT_ERROR       ;long jump to error routine
  199. NO_INT_ERROR:
  200.  
  201.         CMP     BL,25H          ;Interrupt 25 request?
  202.         JZ      Int2526         ;Jump if so
  203.         CMP     BL,26H          ;Interrupt 26 request?
  204.         JNZ     IntNorm         ;Jump if other, "normal" interrupt
  205. Int2526:
  206.         MOV     AX,8            ;[AX] = argument of RETF instructi